﻿using System;
using System.Diagnostics.Contracts;
using System.Net;
using System.Security.Principal;
using System.ServiceModel;
using SharePointContentGenerator.ContentGeneratorLogic.Core;
using SharePointContentGenerator.ContentGeneratorLogic.SharePointWebServiceCopy;
using SharePointContentGenerator.ContentGeneratorLogic.SharePointWebServiceLists;

namespace SharePointContentGenerator.ContentGeneratorLogic.ContentGenerators
{
    internal abstract class SharePointController : ContentGeneratorNotification
    {
        internal TokenImpersonationLevel ImpersonationLevel { get; private set; }
        internal string Domain { get; private set; }
        internal string Username { get; private set; }
        internal string Password { get; private set; }
        internal string SiteCollection { get; private set; }
        
        internal SharePointController(string siteCollection)
        {
            ImpersonationLevel = TokenImpersonationLevel.Impersonation;
            SiteCollection = GetWebServiceReference(siteCollection);
            Domain = string.Empty;
            Username = string.Empty;
            Password = string.Empty;
        }

        internal SharePointController(string siteCollection, string domain, string username, string password)
        {
            ImpersonationLevel = TokenImpersonationLevel.Impersonation;
            SiteCollection = GetWebServiceReference(siteCollection);
            Domain = domain.Trim();
            Username = username.Trim();
            Password = password.Trim();
        }

        private ListsSoapClient GetListClient()
        {
            if (SiteCollection.Length > 0)
            {
                ListsSoapClient client = new ListsSoapClient();

                string webServiceLocation = string.Format("{0}/_vti_bin/Lists.asmx", SiteCollection);
                client.Endpoint.Address = new EndpointAddress(webServiceLocation);
                client.ClientCredentials.Windows.AllowedImpersonationLevel = ImpersonationLevel;

                if (Username.Length > 0)
                    client.ClientCredentials.Windows.ClientCredential = new NetworkCredential(Username, Password, Domain);

                return client;
            }
            else
                throw new InvalidOperationException("GetListClient: Site Collection has not been initialised");
        }

        private CopySoapClient GetCopyClient()
        {
            if (SiteCollection.Length > 0)
            {
                CopySoapClient client = new CopySoapClient();

                string webServiceLocation = string.Format("{0}/_vti_bin/Copy.asmx", SiteCollection);
                client.Endpoint.Address = new EndpointAddress(webServiceLocation);
                client.ClientCredentials.Windows.AllowedImpersonationLevel = ImpersonationLevel;

                if (Username.Length > 0)
                    client.ClientCredentials.Windows.ClientCredential = new NetworkCredential(Username, Password, Domain);

                return client;
            }
            else
                throw new InvalidOperationException("GetCopyclient: Site Collection has not been initialised");
        }

        private string GetWebServiceReference(string siteCollection)
        {
            return siteCollection.EndsWith("/")
                ? siteCollection.Substring(0, siteCollection.Length - 1).Trim()
                : siteCollection.Trim();
        }

        private ListsSoapClient _ListClient;
        
        internal ListsSoapClient ListClient
        {
            get 
            {
                if (_ListClient == null)
                {
                    _ListClient = GetListClient();
                }

                return _ListClient;
            }
        }

        private CopySoapClient _CopyClient;

        internal CopySoapClient CopyClient
        {
            get
            {
                if (_CopyClient == null)
                {
                    _CopyClient = GetCopyClient();
                }

                return _CopyClient;
            }
        }
    }
}
